package pt.iscte.dcti.es.rhplus.gestao;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.sql.SQLException;
import java.util.Hashtable;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import pt.iscte.dcti.es.rhplus.sistema.CodigoPostal;
import pt.iscte.dcti.es.rhplus.sistema.ContaDeUtilizador;
import pt.iscte.dcti.es.rhplus.sistema.Hospital;
import pt.iscte.dcti.es.rhplus.sistema.Seguranca;
import pt.iscte.dcti.es.rhplus.sistema.UtensiliosParaDatas;
import pt.iscte.dcti.es.rhplus.sistema.UtensiliosParaStrings;
import pt.iscte.dcti.es.rhplus.utilizador.Administrativo;
import pt.iscte.dcti.es.rhplus.utilizador.Colaborador;
import pt.iscte.dcti.es.rhplus.utilizador.Enfermeiro;
import pt.iscte.dcti.es.rhplus.utilizador.Medico;
import pt.iscte.dcti.es.rhplus.utilizador.Pessoa;

/**
 * Servlet implementation class for Servlet: GestorDeColaboradores
 * 
 * @author Gustavo Cabral
 * @author Helena Monteiro
 * @author Joao Catarino
 * @author Tiago Moreiras
 */
@SuppressWarnings("serial")
public class GestorDeColaboradores extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {

	/*
	 * (non-Java-doc)
	 * 
	 * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest request,
	 *      HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session = request.getSession();
		String accao = (String) request.getParameter("accao");

		if (accao.equals(GestorDeColaboradores.INSERIR_COLABORADOR))
			inserirColaborador(request, response, session);
		else if (accao.equals(GestorDeColaboradores.ALTERAR_COLABORADOR))
			alterarColaborador(request, response, session);
		else if (accao.equals(GestorDeColaboradores.REMOVER_COLABORADOR))
			removerColaborador(request, response, session);
		else if (accao.equals(GestorDeColaboradores.VISUALIZAR_COLABORADOR))
			visualizarColaborador(request, response, session);
		else if (accao.equals(GestorDeColaboradores.VISUALIZAR_COLABORADORES))
			visualizarColaboradores(request, response, session);
		else {
			IllegalArgumentException illegal_argument_exception = new IllegalArgumentException();
			session.setAttribute("excepcao", illegal_argument_exception.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		}
	}

	/*
	 * (non-Java-doc)
	 * 
	 * @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest request,
	 *      HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

	public void inserirColaborador(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
		try {

			String sub_accao = (String) request.getParameter("sub_accao");
			if (sub_accao != null && sub_accao.equals("primeira")) {

				session.setAttribute("horarios_trabalho", Colaborador.devolveHorariosDeTrabalho());
				session.setAttribute("especialidades", Colaborador.devolveTodasAsEspecialidades());
				session.setAttribute("hospitais", Hospital.devolveTodos());

				response.sendRedirect("/RHPlus/inserirColaborador.jsp");
			} else if (sub_accao != null && sub_accao.equals("segunda")) {

				if (dadosEstaoValidos(request, GestorDeColaboradores.INSERIR_COLABORADOR)) {
					Hashtable<String, Object> dados_do_colaborador = populaTabelaInserirColaborador(request);

					// Verificar se o codigo postal existe
					// Senao existir inserir na base de dados
					int prefixo_codigo_postal = (Integer) dados_do_colaborador.get("var_prefixo_codigo_postal");
					int sufixo_codigo_postal = (Integer) dados_do_colaborador.get("var_sufixo_codigo_postal");
					if (!CodigoPostal.existe(prefixo_codigo_postal, sufixo_codigo_postal))
						CodigoPostal.insere(populaTabelaCodigoPostal(request));

					int id_codigo_postal = CodigoPostal.devolveUltimoIdentificadorDeInsercao();
					dados_do_colaborador.put("var_id_codigo_postal", new Integer(id_codigo_postal));

					String tipo = (String) dados_do_colaborador.get("var_tipo");
					if (tipo.equals(Colaborador.MEDICO))
						Medico.insere(dados_do_colaborador);
					else if (tipo.equals(Colaborador.ENFERMEIRO))
						Enfermeiro.insere(dados_do_colaborador);
					else if (tipo.equals(Colaborador.ADMINISTRATIVO))
						Administrativo.insere(dados_do_colaborador);

					int id_pessoa = Pessoa.devolveUltimoIdentificadorDeInsercao();
					Hashtable<String, Object> dados_da_conta_de_utilizador = populaTabelaContaDeUtilizador(request);
					dados_da_conta_de_utilizador.put("var_id_pessoa", new Integer(id_pessoa));

					if (tipo.equals(Colaborador.MEDICO))
						dados_da_conta_de_utilizador.put("var_perfil", "medico");
					else if (tipo.equals(Colaborador.ENFERMEIRO))
						dados_da_conta_de_utilizador.put("var_perfil", "enfermeiro");
					else if (tipo.equals(Colaborador.ADMINISTRATIVO))
						dados_da_conta_de_utilizador.put("var_perfil", "administrativo");

					ContaDeUtilizador.insere(dados_da_conta_de_utilizador);
                                        
                                        session.removeAttribute("erros");
					response.sendRedirect("/RHPlus/Gestor?gestor=gestor_de_colaboradores&accao=inserir_colaborador&sub_accao=primeira");
				} else {
					session.setAttribute("erros", devolveTabelaDeErrosParaInserirColaborador(request));

					// Propaga dados, previamente inseridos, pela sessao
					session.setAttribute("nome", request.getParameter("nome"));
					session.setAttribute("sexo", request.getParameter("sexo"));
					session.setAttribute("bi", request.getParameter("bi"));
					session.setAttribute("data_de_nascimento_ano", request.getParameter("data_de_nascimento_ano"));
					session.setAttribute("data_de_nascimento_mes", request.getParameter("data_de_nascimento_mes"));
					session.setAttribute("data_de_nascimento_dia", request.getParameter("data_de_nascimento_dia"));
					session.setAttribute("nif", request.getParameter("nif"));
					session.setAttribute("email", request.getParameter("email"));
					session.setAttribute("telefone", request.getParameter("telefone"));
					session.setAttribute("telemovel", request.getParameter("telemovel"));
					session.setAttribute("morada", request.getParameter("morada"));
					session.setAttribute("prefixo_codigo_postal", request.getParameter("prefixo_codigo_postal"));
					session.setAttribute("sufixo_codigo_postal", request.getParameter("sufixo_codigo_postal"));
					session.setAttribute("localidade", request.getParameter("localidade"));
					session.setAttribute("grupo_sanguineo", request.getParameter("grupo_sanguineo"));
					session.setAttribute("nib", request.getParameter("nib"));
					session.setAttribute("nss", request.getParameter("nss"));
					session.setAttribute("data_de_admissao_dia", request.getParameter("data_de_admissao_dia"));
					session.setAttribute("data_de_admissao_mes", request.getParameter("data_de_admissao_mes"));
					session.setAttribute("data_de_admissao_ano", request.getParameter("data_de_admissao_ano"));
					session.setAttribute("vencimento", request.getParameter("vencimento"));
					session.setAttribute("validade_contrato_dia", request.getParameter("validade_contrato_dia"));
					session.setAttribute("validade_contrato_mes", request.getParameter("validade_contrato_mes"));
					session.setAttribute("validade_contrato_ano", request.getParameter("validade_contrato_ano"));
					session.setAttribute("horario_trabalho", request.getParameter("horario_trabalho"));
					session.setAttribute("tipo", request.getParameter("tipo"));

					if (((String) request.getParameter("tipo")).equals("medico"))
						session.setAttribute("especialidade", request.getParameter("especialidade"));

					session.setAttribute("id_hospital", request.getParameter("id_hospital"));
					session.setAttribute("username", request.getParameter("username"));

					response.sendRedirect("/RHPlus/inserirColaborador.jsp");
				}
			} else {
				session.setAttribute("excepcao", "Url incorrecto.");
				response.sendRedirect("/RHPlus/mostra_erro.jsp");
			}

		} catch (SQLException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		} catch (ClassNotFoundException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		} catch (InstantiationException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		} catch (IllegalAccessException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		} catch (NoSuchAlgorithmException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		} catch (IOException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		}
	}

	public void alterarColaborador(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
		try {
			String sub_accao = (String) request.getParameter("sub_accao");
			if (sub_accao != null && sub_accao.equals("primeira")) {

				int id_pessoa = Integer.parseInt((String) request.getParameter("id"));
				String perfil = ContaDeUtilizador.devolvePerfil(id_pessoa);

				Colaborador colaborador = null;

				if (perfil.equals("medico"))
					colaborador = Medico.devolve(id_pessoa);
				else if (perfil.equals("enfermeiro"))
					colaborador = Enfermeiro.devolve(id_pessoa);
				else if (perfil.equals("administrativo"))
					colaborador = Administrativo.devolve(id_pessoa);

				session.setAttribute("horarios_trabalho", Colaborador.devolveHorariosDeTrabalho());

				session.setAttribute("hospitais", Hospital.devolveTodos());

				// Propaga dados, previamente inseridos, pela sessao
				session.setAttribute("nome", colaborador.getNome());
				session.setAttribute("sexo", String.valueOf(colaborador.getSexo()));
				session.setAttribute("bi", colaborador.getBI());
				session.setAttribute("data_de_nascimento_ano", UtensiliosParaDatas.devolveAnoDaData(colaborador.getDataDeNascimento()));
				session.setAttribute("data_de_nascimento_mes", UtensiliosParaDatas.devolveMesDaData(colaborador.getDataDeNascimento()));
				session.setAttribute("data_de_nascimento_dia", UtensiliosParaDatas.devolveDiaDaData(colaborador.getDataDeNascimento()));
				session.setAttribute("nif", colaborador.getNIF());
				session.setAttribute("email", colaborador.getEmail());
				session.setAttribute("telefone", colaborador.getTelefone());
				session.setAttribute("telemovel", colaborador.getTelemovel());
				session.setAttribute("morada", colaborador.getMorada());
				session.setAttribute("prefixo_codigo_postal", colaborador.getCodigoPostal().getPrefixo());
				session.setAttribute("sufixo_codigo_postal", colaborador.getCodigoPostal().getSufixo());
				session.setAttribute("localidade", colaborador.getCodigoPostal().getLocalidade());
				session.setAttribute("grupo_sanguineo", colaborador.getGrupoSanguineo());
				session.setAttribute("nib", colaborador.getNib());
				session.setAttribute("nss", colaborador.getNss());
				session.setAttribute("data_de_admissao_ano", UtensiliosParaDatas.devolveAnoDaData(colaborador.getDataAdmissao()));
				session.setAttribute("data_de_admissao_mes", UtensiliosParaDatas.devolveMesDaData(colaborador.getDataAdmissao()));
				session.setAttribute("data_de_admissao_dia", UtensiliosParaDatas.devolveDiaDaData(colaborador.getDataAdmissao()));
				session.setAttribute("vencimento", colaborador.getVencimento());
				session.setAttribute("validade_contrato_ano", UtensiliosParaDatas.devolveAnoDaData(colaborador.getValidadeContrato()));
				session.setAttribute("validade_contrato_mes", UtensiliosParaDatas.devolveMesDaData(colaborador.getValidadeContrato()));
				session.setAttribute("validade_contrato_dia", UtensiliosParaDatas.devolveDiaDaData(colaborador.getValidadeContrato()));
				session.setAttribute("horario_trabalho", colaborador.getHorarioTrabalho());

				session.setAttribute("tipo", colaborador.getTipo());

				if (perfil.equals("medico"))
					session.setAttribute("especialidade", ((Medico) colaborador).getEspecialidade());

				session.setAttribute("id_hospital", colaborador.getIdHospital());
				session.setAttribute("id_pessoa", id_pessoa);

				session.setAttribute("existem_dados", new Boolean(true));

				response.sendRedirect("/RHPlus/alterarColaborador.jsp");
			} else if (sub_accao != null && sub_accao.equals("segunda")) {
				if (dadosEstaoValidos(request, GestorDeColaboradores.ALTERAR_COLABORADOR)) {
					Hashtable<String, Object> dados_do_colaborador = populaTabelaAlterarColaborador(request);

					if (!((String) session.getAttribute("tipo")).equals("administrativo"))
						dados_do_colaborador.put("var_vencimento", (Double) session.getAttribute("vencimento"));
					else
						dados_do_colaborador.put("var_vencimento", Double.parseDouble(request.getParameter("vencimento")));

					// Verificar se o codigo postal existe
					// Senao existir inserir na base de dados
					int id_pessoa = Integer.parseInt((String) request.getParameter("id"));
					dados_do_colaborador.put("var_id_pessoa", id_pessoa);

					int prefixo_codigo_postal = (Integer) dados_do_colaborador.get("var_prefixo_codigo_postal");
					int sufixo_codigo_postal = (Integer) dados_do_colaborador.get("var_sufixo_codigo_postal");
					if (!CodigoPostal.existe(prefixo_codigo_postal, sufixo_codigo_postal)) {
						CodigoPostal.insere(populaTabelaCodigoPostal(request));
						int id_codigo_postal = CodigoPostal.devolveUltimoIdentificadorDeInsercao();
						dados_do_colaborador.put("var_id_codigo_postal", new Integer(id_codigo_postal));
					} else {
						CodigoPostal codigo_postal = CodigoPostal.devolve(prefixo_codigo_postal, sufixo_codigo_postal);
						int id_codigo_postal = codigo_postal.getIdCodigoPostal();
						dados_do_colaborador.put("var_id_codigo_postal", new Integer(id_codigo_postal));
					}

					String tipo = (String) session.getAttribute("tipo");
					if (tipo.equals(Colaborador.MEDICO))
						Medico.altera(dados_do_colaborador);
					else if (tipo.equals(Colaborador.ENFERMEIRO))
						Enfermeiro.altera(dados_do_colaborador);
					else if (tipo.equals(Colaborador.ADMINISTRATIVO))
						Administrativo.altera(dados_do_colaborador);

					String password_nova = request.getParameter("password_nova");
					if (password_nova != null && !password_nova.equals("")) {
						String username = ContaDeUtilizador.devolveUsername(id_pessoa);
						ContaDeUtilizador.alteraPassword(username, Seguranca.converteParaMD5(password_nova));
					}
					// Remove eventual persistencia da hashtable erros na
					// sessao.
					session.removeAttribute("erros");

					response.sendRedirect("Gestor?gestor=gestor_de_colaboradores&accao=visualizar_colaborador&id=" + id_pessoa);

				} else {
					session.setAttribute("erros", devolveTabelaDeErrosParaAlterarColaborador(request));

					// Propaga dados, previamente inseridos, pela sessao

					session.setAttribute("nome", request.getParameter("nome"));
					session.setAttribute("sexo", request.getParameter("sexo"));
					session.setAttribute("bi", request.getParameter("bi"));
					session.setAttribute("data_de_nascimento_ano", request.getParameter("data_de_nascimento_ano"));
					session.setAttribute("data_de_nascimento_mes", request.getParameter("data_de_nascimento_mes"));
					session.setAttribute("data_de_nascimento_dia", request.getParameter("data_de_nascimento_dia"));
					session.setAttribute("nif", request.getParameter("nif"));
					session.setAttribute("email", request.getParameter("email"));
					session.setAttribute("telefone", request.getParameter("telefone"));
					session.setAttribute("telemovel", request.getParameter("telemovel"));
					session.setAttribute("morada", request.getParameter("morada"));
					session.setAttribute("prefixo_codigo_postal", request.getParameter("prefixo_codigo_postal"));
					session.setAttribute("sufixo_codigo_postal", request.getParameter("sufixo_codigo_postal"));
					session.setAttribute("localidade", request.getParameter("localidade"));
					session.setAttribute("grupo_sanguineo", request.getParameter("grupo_sanguineo"));
					session.setAttribute("nib", request.getParameter("nib"));
					session.setAttribute("nss", request.getParameter("nss"));
					session.setAttribute("data_de_admissao_dia", request.getParameter("data_de_admissao_dia"));
					session.setAttribute("data_de_admissao_mes", request.getParameter("data_de_admissao_mes"));
					session.setAttribute("data_de_admissao_ano", request.getParameter("data_de_admissao_ano"));

					session.setAttribute("validade_contrato_dia", request.getParameter("validade_contrato_dia"));
					session.setAttribute("validade_contrato_mes", request.getParameter("validade_contrato_mes"));
					session.setAttribute("validade_contrato_ano", request.getParameter("validade_contrato_ano"));
					session.setAttribute("horario_trabalho", request.getParameter("horario_trabalho"));

					session.setAttribute("id_hospital", Integer.parseInt(request.getParameter("id_hospital")));
					session.setAttribute("username", request.getParameter("username"));

					response.sendRedirect("/RHPlus/alterarColaborador.jsp");
				}
			} else {
				session.setAttribute("excepcao", "Url incorrecto.");
				response.sendRedirect("/RHPlus/mostra_erro.jsp");
			}

		} catch (SQLException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeUtentes.INSERIR_CLIENTE);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeUtentes.INSERIR_CLIENTE);
		} catch (InstantiationException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeUtentes.INSERIR_CLIENTE);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeUtentes.INSERIR_CLIENTE);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeUtentes.INSERIR_CLIENTE);
		}
	}

	public void removerColaborador(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
		try {
			int numero_de_colaborador = Integer.getInteger((String) request.getParameter("numero_de_colaborador"));
			Colaborador.remove(numero_de_colaborador);

		} catch (SQLException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeUtentes.ALTERAR_CLIENTE);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeUtentes.ALTERAR_CLIENTE);
		} catch (InstantiationException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeUtentes.ALTERAR_CLIENTE);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeUtentes.ALTERAR_CLIENTE);
		}
	}

	public void visualizarColaborador(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
		try {
			int numero_de_colaborador = Integer.parseInt(request.getParameter("id"));
			String perfil = ContaDeUtilizador.devolvePerfil(numero_de_colaborador);

			Colaborador colaborador = null;
			if (perfil.equals("medico"))
				colaborador = Medico.devolve(numero_de_colaborador);
			else if (perfil.equals("administrativo"))
				colaborador = Administrativo.devolve(numero_de_colaborador);
			else if (perfil.equals("enfermeiro"))
				colaborador = Enfermeiro.devolve(numero_de_colaborador);

			session.setAttribute("colaborador", colaborador);
			session.setAttribute("username", ContaDeUtilizador.devolveUsername(numero_de_colaborador));

			session.setAttribute("hospital", Hospital.devolve(colaborador.getIdHospital()).getNome());

			if (perfil.equals("medico")) {
				Medico medico = Medico.devolve(numero_de_colaborador);
				session.setAttribute("medico", medico);
			}

			response.sendRedirect("/RHPlus/mostrar_colaborador.jsp");
		} catch (SQLException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeUtentes.ALTERAR_CLIENTE);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeUtentes.ALTERAR_CLIENTE);
		} catch (InstantiationException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeUtentes.ALTERAR_CLIENTE);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeUtentes.ALTERAR_CLIENTE);
		} catch (IOException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		}
	}

	public void visualizarColaboradores(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
		try {
			session.setAttribute("colaboradores", Colaborador.devolveTodos());
			
		} catch (SQLException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeUtentes.ALTERAR_CLIENTE);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeUtentes.ALTERAR_CLIENTE);
		} catch (InstantiationException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeUtentes.ALTERAR_CLIENTE);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeUtentes.ALTERAR_CLIENTE);
		}
	}

	private Hashtable<String, Object> populaTabelaInserirPessoa(final HttpServletRequest request) throws NoSuchAlgorithmException {

		Hashtable<String, Object> dados = new Hashtable<String, Object>();

		dados.put("var_nome", (String) request.getParameter("nome"));
		dados.put("var_sexo", (String) request.getParameter("sexo"));
		dados.put("var_bi", Integer.parseInt((String) request.getParameter("bi")));

		// Data de Nascimento
		dados.put("var_data_de_nascimento", UtensiliosParaDatas.devolveDataEmString(Integer.parseInt((String) request
				.getParameter("data_de_nascimento_ano")), Integer.parseInt((String) request.getParameter("data_de_nascimento_mes")), Integer
				.parseInt((String) request.getParameter("data_de_nascimento_dia"))));

		dados.put("var_nif", Integer.parseInt((String) request.getParameter("nif")));
		dados.put("var_email", (String) request.getParameter("email"));
		dados.put("var_telefone", Integer.parseInt((String) request.getParameter("telefone")));
		dados.put("var_telemovel", Integer.parseInt((String) request.getParameter("telemovel")));
		dados.put("var_morada", (String) request.getParameter("morada"));

		dados.put("var_prefixo_codigo_postal", Integer.parseInt((String) request.getParameter("prefixo_codigo_postal")));
		dados.put("var_sufixo_codigo_postal", Integer.parseInt((String) request.getParameter("sufixo_codigo_postal")));
		dados.put("var_localidade", (String) request.getParameter("localidade"));

		dados.put("var_grupo_sanguineo", (String) request.getParameter("grupo_sanguineo"));
		dados.put("var_username", (String) request.getParameter("username"));

		String password = (String) request.getParameter("password");
		dados.put("var_password", Seguranca.converteParaMD5(password));

		return dados;
	}

	private Hashtable<String, Object> populaTabelaInserirColaborador(final HttpServletRequest request) throws NoSuchAlgorithmException {

		Hashtable<String, Object> dados = populaTabelaInserirPessoa(request);

		dados.put("var_nib", (String) request.getParameter("nib"));
		dados.put("var_nss", (String) request.getParameter("nss"));

		// Data de admissão
		dados.put("var_data_admissao", UtensiliosParaDatas.devolveDataEmString(Integer
				.parseInt((String) request.getParameter("data_de_admissao_ano")), Integer.parseInt((String) request
				.getParameter("data_de_admissao_mes")), Integer.parseInt((String) request.getParameter("data_de_admissao_dia"))));
		dados.put("var_vencimento", (String) request.getParameter("vencimento"));

		// Data de validade de contrato
		dados.put("var_validade_contrato", UtensiliosParaDatas.devolveDataEmString(Integer.parseInt((String) request
				.getParameter("validade_contrato_ano")), Integer.parseInt((String) request.getParameter("validade_contrato_mes")), Integer
				.parseInt((String) request.getParameter("validade_contrato_dia"))));
		dados.put("var_horario_trabalho", (String) request.getParameter("horario_trabalho"));
		dados.put("var_tipo", (String) request.getParameter("tipo"));
		if (((String) request.getParameter("tipo")).equals("medico"))
			dados.put("var_especialidade", (String) request.getParameter("especialidade"));

		dados.put("var_id_hospital", (String) request.getParameter("id_hospital"));

		return dados;
	}

	private Hashtable<String, Object> populaTabelaAlterarColaborador(final HttpServletRequest request) throws NoSuchAlgorithmException {

		Hashtable<String, Object> dados = populaTabelaAlterarPessoa(request);

		dados.put("var_nib", (String) request.getParameter("nib"));
		dados.put("var_nss", (String) request.getParameter("nss"));

		// Data de admissão
		dados.put("var_data_admissao", UtensiliosParaDatas.devolveDataEmString(Integer
				.parseInt((String) request.getParameter("data_de_admissao_ano")), Integer.parseInt((String) request
				.getParameter("data_de_admissao_mes")), Integer.parseInt((String) request.getParameter("data_de_admissao_dia"))));

		// Data de validade de contrato
		dados.put("var_validade_contrato", UtensiliosParaDatas.devolveDataEmString(Integer.parseInt((String) request
				.getParameter("validade_contrato_ano")), Integer.parseInt((String) request.getParameter("validade_contrato_mes")), Integer
				.parseInt((String) request.getParameter("validade_contrato_dia"))));
		dados.put("var_horario_trabalho", (String) request.getParameter("horario_trabalho"));

		dados.put("var_id_hospital", (String) request.getParameter("id_hospital"));

		return dados;
	}

	private Hashtable<String, Object> populaTabelaAlterarPessoa(final HttpServletRequest request) throws NoSuchAlgorithmException {

		Hashtable<String, Object> dados = new Hashtable<String, Object>();

		dados.put("var_nome", (String) request.getParameter("nome"));
		dados.put("var_sexo", (String) request.getParameter("sexo"));
		dados.put("var_bi", Integer.parseInt((String) request.getParameter("bi")));

		// Data de Nascimento
		dados.put("var_data_de_nascimento", UtensiliosParaDatas.devolveDataEmString(Integer.parseInt((String) request
				.getParameter("data_de_nascimento_ano")), Integer.parseInt((String) request.getParameter("data_de_nascimento_mes")), Integer
				.parseInt((String) request.getParameter("data_de_nascimento_dia"))));

		dados.put("var_nif", Integer.parseInt((String) request.getParameter("nif")));
		dados.put("var_email", (String) request.getParameter("email"));
		dados.put("var_telefone", Integer.parseInt((String) request.getParameter("telefone")));
		dados.put("var_telemovel", Integer.parseInt((String) request.getParameter("telemovel")));
		dados.put("var_morada", (String) request.getParameter("morada"));

		if (((String) request.getParameter("id_codigo_postal")) != null)
			dados.put("var_id_codigo_postal", Integer.parseInt((String) request.getParameter("id_codigo_postal")));
		else {
			dados.put("var_prefixo_codigo_postal", Integer.parseInt((String) request.getParameter("prefixo_codigo_postal")));
			dados.put("var_sufixo_codigo_postal", Integer.parseInt((String) request.getParameter("sufixo_codigo_postal")));
			dados.put("var_localidade", (String) request.getParameter("localidade"));
		}

		dados.put("var_grupo_sanguineo", (String) request.getParameter("grupo_sanguineo"));
		dados.put("var_username", (String) request.getParameter("username"));

		String password = (String) request.getParameter("password");

		if (password != null)
			dados.put("var_password", Seguranca.converteParaMD5(password));

		return dados;
	}

	private Hashtable<String, Object> populaTabelaCodigoPostal(final HttpServletRequest request) {
		Hashtable<String, Object> dados = new Hashtable<String, Object>();

		dados.put("var_prefixo_codigo_postal", Integer.parseInt((String) request.getParameter("prefixo_codigo_postal")));
		dados.put("var_sufixo_codigo_postal", Integer.parseInt((String) request.getParameter("sufixo_codigo_postal")));
		dados.put("var_localidade", (String) request.getParameter("localidade"));

		return dados;
	}

	private Hashtable<String, Object> populaTabelaContaDeUtilizador(final HttpServletRequest request) throws NoSuchAlgorithmException {
		Hashtable<String, Object> dados = new Hashtable<String, Object>();

		dados.put("var_username", (String) request.getParameter("username"));

		String password = (String) request.getParameter("password");
		dados.put("var_password", Seguranca.converteParaMD5(password));

		return dados;
	}

	private boolean dadosEstaoValidos(final HttpServletRequest request, final String action) throws SQLException, ClassNotFoundException,
			InstantiationException, IllegalAccessException {
		return devolveTabelaDeErros(request, action).isEmpty();
	}

	private Hashtable<String, String> devolveTabelaDeErros(final HttpServletRequest request, final String action) throws SQLException,
			ClassNotFoundException, InstantiationException, IllegalAccessException {
		if (action.equals(GestorDeColaboradores.INSERIR_COLABORADOR))
			return devolveTabelaDeErrosParaInserirColaborador(request);
		else if (action.equals(GestorDeColaboradores.ALTERAR_COLABORADOR))
			return devolveTabelaDeErrosParaAlterarColaborador(request);
		else
			return new Hashtable<String, String>();
	}

	private Hashtable<String, String> devolveTabelaDeErrosParaInserirColaborador(final HttpServletRequest request) throws SQLException,
			ClassNotFoundException, InstantiationException, IllegalAccessException {

		Hashtable<String, String> tabela_de_erros = devolveTabelaDeErrosParaInserirPessoa(request);

		String tipo = (String) request.getParameter("tipo");
		if (tipo == null || tipo.trim().equals(""))
			tabela_de_erros.put("tipo", "Campo Obrigatório. Não pode estar vazio.");
		else if (!tipo.equals(Colaborador.MEDICO) && !tipo.equals(Colaborador.ADMINISTRATIVO) && !tipo.equals(Colaborador.ENFERMEIRO))
			tabela_de_erros.put("tipo", "Valor inválido. Deverá ser médico, administrativo ou enfermeiro.");

		String nib = (String) request.getParameter("nib");
		if (nib == null || nib.trim().equals(""))
			tabela_de_erros.put("nib", "Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(nib))
			tabela_de_erros.put("nib", "O campo NIB deverá ser numérico.");
		else if (nib.length() != 21)
			tabela_de_erros.put("nib", "NIB inválido. Deverá ter 21 caracteres.");

		String nss = (String) request.getParameter("nss");
		if (nss == null || nss.trim().equals(""))
			tabela_de_erros.put("nss", "Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(nss))
			tabela_de_erros.put("nss", "O campo NSS deverá ser numérico.");
		else if (nss.length() != 11)
			tabela_de_erros.put("nss", "NISS inválido. Deverá ter 11 caracteres.");

		String vencimento = (String) request.getParameter("vencimento");
		if (vencimento == null || vencimento.trim().equals(""))
			tabela_de_erros.put("vencimento", "Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumeroReal(vencimento))
			tabela_de_erros.put("vencimento", "O campo vencimento deverá ser numérico.");
		else if (Double.parseDouble(vencimento) < 0)
			tabela_de_erros.put("vencimento", "O vencimento deverá ser superior a 0.");

		// Data de admissão

		int data_admissao_ano = -1;
		int data_admissao_mes = -1;
		int data_admissao_dia = -1;
		String data_de_admissao_ano = (String) request.getParameter("data_de_admissao_ano");
		if (data_de_admissao_ano == null || data_de_admissao_ano.trim().equals(""))
			tabela_de_erros.put("data_de_admissao_ano", "Ano: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(data_de_admissao_ano))
			tabela_de_erros.put("data_de_admissao_ano", "O campo ano da data de admissão deverá ser numérico.");

		String data_de_admissao_mes = (String) request.getParameter("data_de_admissao_mes");
		if (data_de_admissao_mes == null || data_de_admissao_mes.trim().equals(""))
			tabela_de_erros.put("data_de_admissao_mes", "Mês: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(data_de_admissao_mes))
			tabela_de_erros.put("data_de_admissao_mes", "O campo mês da data de admissão deverá ser numérico.");

		String data_de_admissao_dia = (String) request.getParameter("data_de_admissao_dia");
		if (data_de_admissao_dia == null || data_de_admissao_dia.trim().equals(""))
			tabela_de_erros.put("data_de_admissao_dia", "Dia: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(data_de_admissao_dia))
			tabela_de_erros.put("data_de_admissao_dia", "O campo dia da data de admissão deverá ser numérico.");

		if (data_de_admissao_ano != null && !data_de_admissao_ano.trim().equals("") && UtensiliosParaStrings.eUmNumero(data_de_admissao_ano)
				&& data_de_admissao_mes != null && !data_de_admissao_mes.trim().equals("") && UtensiliosParaStrings.eUmNumero(data_de_admissao_mes)
				&& data_de_admissao_dia != null && !data_de_admissao_dia.trim().equals("") && UtensiliosParaStrings.eUmNumero(data_de_admissao_dia)) {
			int ano = Integer.parseInt(data_de_admissao_ano);
			int mes = Integer.parseInt(data_de_admissao_mes);
			int dia = Integer.parseInt(data_de_admissao_dia);
			if (!UtensiliosParaDatas.eValida(ano, mes, dia))
				tabela_de_erros.put("data_de_admissao", "Formato de Data Errado.");
		}

		// Validade do contrato
		String validade_contrato_ano = (String) request.getParameter("validade_contrato_ano");
		if (validade_contrato_ano == null || validade_contrato_ano.trim().equals(""))
			tabela_de_erros.put("validade_contrato_ano", "Ano: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(validade_contrato_ano))
			tabela_de_erros.put("validade_contrato_ano", "O campo ano da data de validade de contrato deverá ser numérico.");

		String validade_contrato_mes = (String) request.getParameter("validade_contrato_mes");
		if (validade_contrato_mes == null || validade_contrato_mes.trim().equals(""))
			tabela_de_erros.put("validade_contrato_mes", "Mês: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(validade_contrato_mes))
			tabela_de_erros.put("validade_contrato_mes", "O campo mês da data de validade de contrato deverá ser numérico.");

		String validade_contrato_dia = (String) request.getParameter("validade_contrato_dia");
		if (validade_contrato_dia == null || validade_contrato_dia.trim().equals(""))
			tabela_de_erros.put("validade_contrato_dia", "Dia: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(validade_contrato_dia))
			tabela_de_erros.put("validade_contrato_dia", "O campo dia da data de validade de contrato deverá ser numérico.");

		if (validade_contrato_ano != null && !validade_contrato_ano.trim().equals("") && UtensiliosParaStrings.eUmNumero(validade_contrato_ano)
				&& validade_contrato_mes != null && !validade_contrato_mes.trim().equals("")
				&& UtensiliosParaStrings.eUmNumero(validade_contrato_mes) && validade_contrato_dia != null
				&& !validade_contrato_dia.trim().equals("") && UtensiliosParaStrings.eUmNumero(validade_contrato_dia)) {
			int ano = Integer.parseInt(validade_contrato_ano);
			int mes = Integer.parseInt(validade_contrato_mes);
			int dia = Integer.parseInt(validade_contrato_dia);
			if (!UtensiliosParaDatas.eValida(ano, mes, dia)) {
				if (UtensiliosParaDatas.eMaiorDoQue(UtensiliosParaDatas.devolveData(ano, mes, dia), UtensiliosParaDatas.devolveData(
						data_admissao_ano, data_admissao_mes, data_admissao_dia)))
					tabela_de_erros.put("validade_de_contrato", "Formato de Data Errado.");
			}
		}

		String especialidade = (String) request.getParameter("especialidade");
		if ((tipo != null && tipo.equals(Colaborador.MEDICO)) && (especialidade == null || especialidade.trim().equals("")))
			tabela_de_erros.put("especialidade", "Campo Obrigatório. Não pode estar vazio.");

		String horario_trabalho = (String) request.getParameter("horario_trabalho");
		if (horario_trabalho == null || horario_trabalho.trim().equals(""))
			tabela_de_erros.put("horario_trabalho", "Campo Obrigatório. Não pode estar vazio.");

		String id_hospital = (String) request.getParameter("id_hospital");
		if (id_hospital == null || id_hospital.trim().equals(""))
			tabela_de_erros.put("id_hospital", "Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(id_hospital))
			tabela_de_erros.put("id_hospital", "Deverá seleccionar um hospital.");

		return tabela_de_erros;
	}

	private Hashtable<String, String> devolveTabelaDeErrosParaAlterarColaborador(final HttpServletRequest request) {

		Hashtable<String, String> tabela_de_erros = devolveTabelaDeErrosParaAlterarPessoa(request);

		String nib = request.getParameter("nib");
		if (nib == null || nib.trim().equals(""))
			tabela_de_erros.put("nib", "Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(nib))
			tabela_de_erros.put("nib", "O campo NIB deverá ser numérico.");
		else if (nib.length() != 21)
			tabela_de_erros.put("nib", "NIB inválido. Deverá ter 21 caracteres.");

		String nss = request.getParameter("nss");
		if (nss == null || nss.trim().equals(""))
			tabela_de_erros.put("nss", "Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(nss))
			tabela_de_erros.put("nss", "O campo NSS deverá ser numérico.");
		else if (nss.length() != 11)
			tabela_de_erros.put("nss", "NISS inválido. Deverá ter 11 caracteres.");

		// Data de admissão

		String data_de_admissao_ano = request.getParameter("data_de_admissao_ano");
		if (data_de_admissao_ano == null || data_de_admissao_ano.trim().equals(""))
			tabela_de_erros.put("data_de_admissao_ano", "Ano: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(data_de_admissao_ano))
			tabela_de_erros.put("data_de_admissao_ano", "O campo ano da data de admissão deverá ser numérico.");

		String data_de_admissao_mes = request.getParameter("data_de_admissao_mes");
		if (data_de_admissao_mes == null || data_de_admissao_mes.trim().equals(""))
			tabela_de_erros.put("data_de_admissao_mes", "Mês: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(data_de_admissao_mes))
			tabela_de_erros.put("data_de_admissao_mes", "O campo mês da data de admissão deverá ser numérico.");

		String data_de_admissao_dia = request.getParameter("data_de_admissao_dia");
		if (data_de_admissao_dia == null || data_de_admissao_dia.trim().equals(""))
			tabela_de_erros.put("data_de_admissao_dia", "Dia: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(data_de_admissao_dia))
			tabela_de_erros.put("data_de_admissao_dia", "O campo dia da data de admissão deverá ser numérico.");

		if (data_de_admissao_ano != null && !data_de_admissao_ano.trim().equals("") && UtensiliosParaStrings.eUmNumero(data_de_admissao_ano)
				&& data_de_admissao_mes != null && !data_de_admissao_mes.trim().equals("") && UtensiliosParaStrings.eUmNumero(data_de_admissao_mes)
				&& data_de_admissao_dia != null && !data_de_admissao_dia.trim().equals("") && UtensiliosParaStrings.eUmNumero(data_de_admissao_dia)) {
			int ano = Integer.parseInt(data_de_admissao_ano);
			int mes = Integer.parseInt(data_de_admissao_mes);
			int dia = Integer.parseInt(data_de_admissao_dia);
			if (!UtensiliosParaDatas.eValida(ano, mes, dia))
				tabela_de_erros.put("data_de_admissao", "Formato de Data Errado.");
		}

		// Validade do contrato
		String validade_contrato_ano = request.getParameter("validade_contrato_ano");
		if (validade_contrato_ano == null || validade_contrato_ano.trim().equals(""))
			tabela_de_erros.put("validade_contrato_ano", "Ano: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(validade_contrato_ano))
			tabela_de_erros.put("validade_contrato_ano", "O campo ano da data de validade de contrato deverá ser numérico.");

		String validade_contrato_mes = request.getParameter("validade_contrato_mes");
		if (validade_contrato_mes == null || validade_contrato_mes.trim().equals(""))
			tabela_de_erros.put("validade_contrato_mes", "Mês: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(validade_contrato_mes))
			tabela_de_erros.put("validade_contrato_mes", "O campo mês da data de validade de contrato deverá ser numérico.");

		String validade_contrato_dia = request.getParameter("validade_contrato_dia");
		if (validade_contrato_dia == null || validade_contrato_dia.trim().equals(""))
			tabela_de_erros.put("validade_contrato_dia", "Dia: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(validade_contrato_dia))
			tabela_de_erros.put("validade_contrato_dia", "O campo dia da data de validade de contrato deverá ser numérico.");

		if (validade_contrato_ano != null && !validade_contrato_ano.trim().equals("") && UtensiliosParaStrings.eUmNumero(validade_contrato_ano)
				&& validade_contrato_mes != null && !validade_contrato_mes.trim().equals("")
				&& UtensiliosParaStrings.eUmNumero(validade_contrato_mes) && validade_contrato_dia != null
				&& !validade_contrato_dia.trim().equals("") && UtensiliosParaStrings.eUmNumero(validade_contrato_dia)) {
			int ano = Integer.parseInt(validade_contrato_ano);
			int mes = Integer.parseInt(validade_contrato_mes);
			int dia = Integer.parseInt(validade_contrato_dia);
			if (!UtensiliosParaDatas.eValida(ano, mes, dia)) {
				tabela_de_erros.put("validade_contrato", "Formato de Data Errado.");
			} else if (!tabela_de_erros.contains("data_de_admissao")
					&& !tabela_de_erros.contains("data_de_admissao_ano")
					&& !tabela_de_erros.contains("data_de_admissao_mes")
					&& !tabela_de_erros.contains("data_de_admissao_dia")
					&& UtensiliosParaDatas.eValida(Integer.parseInt(data_de_admissao_ano), Integer.parseInt(data_de_admissao_mes), Integer
							.parseInt(data_de_admissao_dia))
					&& !UtensiliosParaDatas.eMaiorDoQue(UtensiliosParaDatas.devolveData(ano, mes, dia), UtensiliosParaDatas.devolveData(Integer
							.parseInt(data_de_admissao_ano), Integer.parseInt(data_de_admissao_mes), Integer.parseInt(data_de_admissao_dia))))

				tabela_de_erros.put("validade_contrato", "Validade Inferior a Data de Admissão.");
		}

		String horario_trabalho = request.getParameter("horario_trabalho");
		if (horario_trabalho == null || horario_trabalho.trim().equals(""))
			tabela_de_erros.put("horario_trabalho", "Campo Obrigatório. Não pode estar vazio.");

		String id_hospital = request.getParameter("id_hospital");
		if (id_hospital == null || id_hospital.trim().equals(""))
			tabela_de_erros.put("id_hospital", "Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(id_hospital))
			tabela_de_erros.put("id_hospital", "Deverá seleccionar um hospital.");

		return tabela_de_erros;
	}

	private Hashtable<String, String> devolveTabelaDeErrosParaInserirPessoa(final HttpServletRequest request) throws SQLException,
			ClassNotFoundException, InstantiationException, IllegalAccessException {

		Hashtable<String, String> tabela_de_erros = new Hashtable<String, String>();

		String nome = (String) request.getParameter("nome");
		if (nome == null || nome.trim().equals(""))
			tabela_de_erros.put("nome", "Campo Obrigatório. Não pode estar vazio.");

		String sexo = (String) request.getParameter("sexo");
		if (sexo == null || sexo.trim().equals(""))
			tabela_de_erros.put("sexo", "Campo Obrigatório. Não pode estar vazio.");
		else if (!(sexo.trim().equals("M") || sexo.trim().equals("F")))
			tabela_de_erros.put("sexo", "Valor inválido. O campo sexo apenas poderá assumir o valor \"M\" ou \"F\".");

		String bi = (String) request.getParameter("bi");
		if (bi == null || bi.trim().equals(""))
			tabela_de_erros.put("bi", "Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(bi))
			tabela_de_erros.put("bi", "O campo BI deverá ser numérico.");
		else if (Integer.parseInt(bi) <= 0 || Integer.parseInt(bi) >= 100000000)
			tabela_de_erros.put("bi", "Número de BI inválido. Deverá estar dentro do intervalo [0-100000000], exclusive.");

		// Data de Nascimento
		String data_de_nascimento_ano = (String) request.getParameter("data_de_nascimento_ano");
		if (data_de_nascimento_ano == null || data_de_nascimento_ano.trim().equals(""))
			tabela_de_erros.put("data_de_nascimento_ano", "Ano: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(data_de_nascimento_ano))
			tabela_de_erros.put("data_de_nascimento_ano", "O campo ano da data de nascimento deverá ser numérico.");

		String data_de_nascimento_mes = (String) request.getParameter("data_de_nascimento_mes");
		if (data_de_nascimento_mes == null || data_de_nascimento_mes.trim().equals(""))
			tabela_de_erros.put("data_de_nascimento_mes", "Mês: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(data_de_nascimento_mes))
			tabela_de_erros.put("data_de_nascimento_mes", "O campo mês da data de nascimento deverá ser numérico.");

		String data_de_nascimento_dia = (String) request.getParameter("data_de_nascimento_dia");
		if (data_de_nascimento_dia == null || data_de_nascimento_dia.trim().equals(""))
			tabela_de_erros.put("data_de_nascimento_dia", "Dia: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(data_de_nascimento_dia))
			tabela_de_erros.put("data_de_nascimento_dia", "O campo dia da data de nascimento deverá ser numérico.");

		if (data_de_nascimento_ano != null && !data_de_nascimento_ano.trim().equals("") && UtensiliosParaStrings.eUmNumero(data_de_nascimento_ano)
				&& data_de_nascimento_mes != null && !data_de_nascimento_mes.trim().equals("")
				&& UtensiliosParaStrings.eUmNumero(data_de_nascimento_mes) && data_de_nascimento_dia != null
				&& !data_de_nascimento_dia.trim().equals("") && UtensiliosParaStrings.eUmNumero(data_de_nascimento_dia)) {
			int ano = Integer.parseInt(data_de_nascimento_ano);
			int mes = Integer.parseInt(data_de_nascimento_mes);
			int dia = Integer.parseInt(data_de_nascimento_dia);
			if (!UtensiliosParaDatas.eValida(ano, mes, dia))
				tabela_de_erros.put("data_de_nascimento", "Formato de Data Errado.");
		}

		String nif = (String) request.getParameter("nif");
		if (nif == null || nif.trim().equals(""))
			tabela_de_erros.put("nif", "Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(nif))
			tabela_de_erros.put("nif", "O campo NIF deverá ser numérico.");
		else if (nif.length() < 8 || nif.length() > 9)
			tabela_de_erros.put("nif", "Número de NIF inválido. Deverá ter entre 8 a 9 caracteres, inclusive.");

		String email = (String) request.getParameter("email");
		if (email == null || email.trim().equals(""))
			tabela_de_erros.put("email", "Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmEmail(email))
			tabela_de_erros.put("email", "Formato de E-Mail Inválido.");

		String telefone = (String) request.getParameter("telefone");
		if (telefone == null || telefone.trim().equals(""))
			tabela_de_erros.put("telefone", "Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(telefone))
			tabela_de_erros.put("telefone", "O campo telefone deverá ser numérico.");

		String telemovel = (String) request.getParameter("telemovel");
		if (telemovel == null || telemovel.trim().equals(""))
			tabela_de_erros.put("telemovel", "Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(telemovel))
			tabela_de_erros.put("telemovel", "O campo telemóvel deverá ser numérico.");

		String morada = (String) request.getParameter("morada");
		if (morada == null || morada.trim().equals(""))
			tabela_de_erros.put("morada", "Campo Obrigatório. Não pode estar vazio.");

		// Codigo Postal
		String prefixo_codigo_postal = (String) request.getParameter("prefixo_codigo_postal");
		if (prefixo_codigo_postal == null || prefixo_codigo_postal.trim().equals(""))
			tabela_de_erros.put("prefixo_codigo_postal", "Prefixo: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(prefixo_codigo_postal))
			tabela_de_erros.put("prefixo_codigo_postal", "O campo prefixo do código postal deverá ser numérico.");

		String sufixo_codigo_postal = (String) request.getParameter("sufixo_codigo_postal");
		if (sufixo_codigo_postal == null || sufixo_codigo_postal.trim().equals(""))
			tabela_de_erros.put("sufixo_codigo_postal", "Sufixo: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(sufixo_codigo_postal))
			tabela_de_erros.put("sufixo_codigo_postal", "O campo sufixo do código postal deverá ser numérico.");

		String localidade = (String) request.getParameter("localidade");
		if (localidade == null || localidade.trim().equals(""))
			tabela_de_erros.put("localidade", "Campo Obrigatório. Não pode estar vazio.");

		String grupo_sanguineo = (String) request.getParameter("grupo_sanguineo");
		if (grupo_sanguineo == null || grupo_sanguineo.trim().equals(""))
			tabela_de_erros.put("grupo_sanguineo", "Campo Obrigatório. Não pode estar vazio.");
		if (!grupo_sanguineo.equals("O+") && !grupo_sanguineo.equals("A+") && !grupo_sanguineo.equals("B+") && !grupo_sanguineo.equals("AB+")
				&& !grupo_sanguineo.equals("O-") && !grupo_sanguineo.equals("A-") && !grupo_sanguineo.equals("B-") && !grupo_sanguineo.equals("AB-")
				&& !grupo_sanguineo.equals("desconhecido"))
			tabela_de_erros.put("grupo_sanguineo", "O Grupo Sanguíneo deverá ter um dos seguintes valores: O+, A+, B+, AB+, O-, A-, B- ou AB-.");

		String username = (String) request.getParameter("username");
		if (username == null || username.trim().equals(""))
			tabela_de_erros.put("username", "Campo Obrigatório. Não pode estar vazio.");
		else if (username.length() < 6)
			tabela_de_erros.put("username", "Tamanho inválido. O campo username deverá ter pelo menos 6 caracteres.");
		else if (ContaDeUtilizador.existeUsername(username))
			tabela_de_erros.put("username", "Username já existente.");

		String password = (String) request.getParameter("password");
		if (password == null || password.trim().equals(""))
			tabela_de_erros.put("password", "Campo Obrigatório. Não pode estar vazio.");
		else if (password.length() < 6)
			tabela_de_erros.put("password", "Tamanho inválido. O campo password deverá ter pelo menos 6 caracteres.");

		String verification_password = (String) request.getParameter("verification_password");
		if (verification_password == null || verification_password.trim().equals(""))
			tabela_de_erros.put("verification_password", "Campo Obrigatório. Não pode estar vazio.");
		else if (!verification_password.equals(password))
			tabela_de_erros.put("verification_password", "Não coincide com a password.");

		return tabela_de_erros;
	}

	private Hashtable<String, String> devolveTabelaDeErrosParaAlterarPessoa(final HttpServletRequest request) {
		Hashtable<String, String> tabela_de_erros = new Hashtable<String, String>();

		String nome = (String) request.getParameter("nome");
		if (nome == null || nome.trim().equals(""))
			tabela_de_erros.put("nome", "Campo Obrigatório. Não pode estar vazio.");

		String sexo = (String) request.getParameter("sexo");
		if (sexo == null || sexo.trim().equals(""))
			tabela_de_erros.put("sexo", "Campo Obrigatório. Não pode estar vazio.");
		else if (!(sexo.trim().equals("M") || sexo.trim().equals("F")))
			tabela_de_erros.put("sexo", "Valor inválido. O campo sexo apenas poderá assumir o valor \"M\" ou \"F\".");

		String bi = (String) request.getParameter("bi");
		if (bi == null || bi.trim().equals(""))
			tabela_de_erros.put("bi", "Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(bi))
			tabela_de_erros.put("bi", "O campo BI deverá ser numérico.");
		else if (Integer.parseInt(bi) <= 0 || Integer.parseInt(bi) >= 100000000)
			tabela_de_erros.put("bi", "Número de BI inválido. Deverá estar dentro do intervalo [0-100000000], exclusive.");

		// Data de Nascimento
		String data_de_nascimento_ano = (String) request.getParameter("data_de_nascimento_ano");
		if (data_de_nascimento_ano == null || data_de_nascimento_ano.trim().equals(""))
			tabela_de_erros.put("data_de_nascimento_ano", "Ano: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(data_de_nascimento_ano))
			tabela_de_erros.put("data_de_nascimento_ano", "O campo ano da data de nascimento deverá ser numérico.");

		String data_de_nascimento_mes = (String) request.getParameter("data_de_nascimento_mes");
		if (data_de_nascimento_mes == null || data_de_nascimento_mes.trim().equals(""))
			tabela_de_erros.put("data_de_nascimento_mes", "Mês: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(data_de_nascimento_mes))
			tabela_de_erros.put("data_de_nascimento_mes", "O campo mês da data de nascimento deverá ser numérico.");

		String data_de_nascimento_dia = (String) request.getParameter("data_de_nascimento_dia");
		if (data_de_nascimento_dia == null || data_de_nascimento_dia.trim().equals(""))
			tabela_de_erros.put("data_de_nascimento_dia", "Dia: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(data_de_nascimento_dia))
			tabela_de_erros.put("data_de_nascimento_dia", "O campo dia da data de nascimento deverá ser numérico.");

		if (data_de_nascimento_ano != null && !data_de_nascimento_ano.trim().equals("") && UtensiliosParaStrings.eUmNumero(data_de_nascimento_ano)
				&& data_de_nascimento_mes != null && !data_de_nascimento_mes.trim().equals("")
				&& UtensiliosParaStrings.eUmNumero(data_de_nascimento_mes) && data_de_nascimento_dia != null
				&& !data_de_nascimento_dia.trim().equals("") && UtensiliosParaStrings.eUmNumero(data_de_nascimento_dia)) {
			int ano = Integer.parseInt(data_de_nascimento_ano);
			int mes = Integer.parseInt(data_de_nascimento_mes);
			int dia = Integer.parseInt(data_de_nascimento_dia);
			if (!UtensiliosParaDatas.eValida(ano, mes, dia))
				tabela_de_erros.put("data_de_nascimento", "Formato de Data Errado.");
		}

		String nif = (String) request.getParameter("nif");
		if (nif == null || nif.trim().equals(""))
			tabela_de_erros.put("nif", "Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(nif))
			tabela_de_erros.put("nif", "O campo NIF deverá ser numérico.");
		else if (nif.length() < 8 || nif.length() > 9)
			tabela_de_erros.put("nif", "Número de NIF inválido. Deverá ter entre 8 a 9 caracteres, inclusive.");

		String email = (String) request.getParameter("email");
		if (email == null || email.trim().equals(""))
			tabela_de_erros.put("email", "Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmEmail(email))
			tabela_de_erros.put("email", "Formato de E-Mail Inválido.");

		String telefone = (String) request.getParameter("telefone");
		if (telefone == null || telefone.trim().equals(""))
			tabela_de_erros.put("telefone", "Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(telefone))
			tabela_de_erros.put("telefone", "O campo telefone deverá ser numérico.");

		String telemovel = (String) request.getParameter("telemovel");
		if (telemovel == null || telemovel.trim().equals(""))
			tabela_de_erros.put("telemovel", "Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(telemovel))
			tabela_de_erros.put("telemovel", "O campo telemóvel deverá ser numérico.");

		String morada = (String) request.getParameter("morada");
		if (morada == null || morada.trim().equals(""))
			tabela_de_erros.put("morada", "Campo Obrigatório. Não pode estar vazio.");

		// Codigo Postal
		String prefixo_codigo_postal = (String) request.getParameter("prefixo_codigo_postal");
		if (prefixo_codigo_postal == null || prefixo_codigo_postal.trim().equals(""))
			tabela_de_erros.put("prefixo_codigo_postal", "Prefixo: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(prefixo_codigo_postal))
			tabela_de_erros.put("prefixo_codigo_postal", "O campo prefixo do código postal deverá ser numérico.");

		String sufixo_codigo_postal = (String) request.getParameter("sufixo_codigo_postal");
		if (sufixo_codigo_postal == null || sufixo_codigo_postal.trim().equals(""))
			tabela_de_erros.put("sufixo_codigo_postal", "Sufixo: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(sufixo_codigo_postal))
			tabela_de_erros.put("sufixo_codigo_postal", "O campo sufixo do código postal deverá ser numérico.");

		String localidade = (String) request.getParameter("localidade");
		if (localidade == null || localidade.trim().equals(""))
			tabela_de_erros.put("localidade", "Campo Obrigatório. Não pode estar vazio.");

		String grupo_sanguineo = (String) request.getParameter("grupo_sanguineo");
		if (grupo_sanguineo == null || grupo_sanguineo.trim().equals(""))
			tabela_de_erros.put("grupo_sanguineo", "Campo Obrigatório. Não pode estar vazio.");
		if (!grupo_sanguineo.equals("O+") && !grupo_sanguineo.equals("A+") && !grupo_sanguineo.equals("B+") && !grupo_sanguineo.equals("AB+")
				&& !grupo_sanguineo.equals("O-") && !grupo_sanguineo.equals("A-") && !grupo_sanguineo.equals("B-") && !grupo_sanguineo.equals("AB-")
				&& !grupo_sanguineo.equals("desconhecido"))
			tabela_de_erros.put("grupo_sanguineo", "O Grupo Sanguíneo deverá ter um dos seguintes valores: O+, A+, B+, AB+, O-, A-, B- ou AB-.");

		String password_antiga = (String) request.getParameter("password_antiga");
		String password_nova = (String) request.getParameter("password_nova");
		String verification_password_nova = (String) request.getParameter("verification_password_nova");

		if (password_antiga != null && password_nova != null && verification_password_nova == null) {
			tabela_de_erros.put("verification_password_nova", "Campo Obrigatório. Não pode estar vazio.");
		}

		else if (password_antiga != null && password_nova == null && verification_password_nova != null) {
			tabela_de_erros.put("password_nova", "Campo Obrigatório. Não pode estar vazio.");
		}

		else if (password_antiga == null && password_nova != null && verification_password_nova != null) {
			tabela_de_erros.put("password_antiga", "Campo Obrigatório. Não pode estar vazio.");
		}

		if (password_antiga != null && password_nova != null && verification_password_nova != null
				&& !verification_password_nova.equals(password_nova))
			tabela_de_erros.put("verification_password", "Não coincide com a password.");

		String password = (String) request.getParameter("password");
		if (password != null && !password.trim().equals("") && password.length() < 6)
			tabela_de_erros.put("password", "Tamanho inválido. O campo password deverá ter pelo menos 6 caracteres.");

		String verification_password = (String) request.getParameter("verification_password");
		if (verification_password != null && !verification_password.trim().equals("") && !verification_password.equals(password))
			tabela_de_erros.put("verification_password", "Não coincide com a password.");

		return tabela_de_erros;
	}

	public static final String INSERIR_COLABORADOR = "inserir_colaborador";
	public static final String ALTERAR_COLABORADOR = "alterar_colaborador";
	public static final String REMOVER_COLABORADOR = "remover_colaborador";
	public static final String VISUALIZAR_COLABORADOR = "visualizar_colaborador";
	public static final String VISUALIZAR_COLABORADORES = "visualizar_colaboradores";
}